package dk.zpon.andnoise;

import java.util.Timer;
import java.util.TimerTask;

import org.json.JSONObject;

import dk.zpon.andnoise.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class Infoscreen extends Activity {

	private Connection mCon;
	private Timer mTimer;
	private Handler mHandler = new Handler();
	private InfoscreenUI mScreenUi;
	private TextView mTime;						// Time progress
	private TextView mTotaltime;				// Total time
	private SeekBar mTimeBar;					// Progress SeekBar
	private TextView mVolume;					// Volume level
	private SeekBar mVolumeBar;					// Volume bar
	private ImageButton mPrevBtn;				// Prev button
	private ImageButton mNextBtn;				// Next button
	private ImageButton mPlayBtn;				// Play button
	private TextView mTitle;					// Title of track		
	//private TextView mStatus;					// Status of player (playing/paused)
	private TextView mArtist;					// Artist
	private TextView mAlbum;					// Album

	// Create runnable for posting
	final Runnable mUpdateResults = new Runnable() {
		public void run() {
			updateResultsInUi();
		}
	};

	final Runnable mUpdateSeekbar = new Runnable() {
		public void run() {
			updateSeekbar();
		}
	};

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{

		super.onCreate(savedInstanceState);
		setContentView(R.layout.infoscreen);

		mScreenUi = new InfoscreenUI();

		mCon = Connection.getInstance();

		mPrevBtn = (ImageButton)findViewById(R.id.prevBtn);
		mPlayBtn = (ImageButton)findViewById(R.id.playBtn);
		mNextBtn = (ImageButton)findViewById(R.id.nextBtn);
		mVolume = (TextView)this.findViewById(R.id.volume);
		mVolumeBar = (SeekBar)this.findViewById(R.id.volumeBar);
		mTime = (TextView)this.findViewById(R.id.time);
		mTimeBar = (SeekBar)this.findViewById(R.id.timeBar);
		mTitle = (TextView)this.findViewById(R.id.title);
		//mStatus = (TextView)this.findViewById(R.id.status);
		mArtist = (TextView)this.findViewById(R.id.artist);
		mAlbum = (TextView)this.findViewById(R.id.album);
		mTotaltime = (TextView)this.findViewById(R.id.totaltime);


		if(mCon.getUsertype() == Usertype.user)
		{			
			mPrevBtn.setEnabled(false);
			mPlayBtn.setEnabled(false);
			mNextBtn.setEnabled(false);
			mVolumeBar.setEnabled(false);
			mTimeBar.setEnabled(false);
		}
		else
		{			
			mVolumeBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener ()
			{
				public void onStopTrackingTouch(SeekBar seekbar)
				{
					try {
						if(mCon.setVolume(seekbar.getProgress()))
						{
							mScreenUi.setVolume(seekbar.getProgress());
							mScreenUi.setTmpVolume(seekbar.getProgress());
							mHandler.post(mUpdateResults);
						}
						else
							mScreenUi.setTmpVolume(mScreenUi.getVolume());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

				@Override
				public void onProgressChanged(SeekBar seekBar, int progress,
						boolean fromTouch) {
					mScreenUi.setTmpVolume(progress);
					mHandler.post(mUpdateResults);
				}

				@Override
				public void onStartTrackingTouch(SeekBar seekBar) {}
			});



			mTimeBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener ()
			{
				public void onStopTrackingTouch(SeekBar seekbar)
				{
					try {
						if(mCon.setPosition(seekbar.getProgress()))
						{
							mScreenUi.setPosition(seekbar.getProgress());
							mScreenUi.setTmpPosition(seekbar.getProgress());
							mHandler.post(mUpdateResults);
						}
						else
							mScreenUi.setTmpPosition(mScreenUi.getPosition());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

				@Override
				public void onProgressChanged(SeekBar seekBar, int progress,
						boolean fromTouch) {
					if(fromTouch)
					{
						mScreenUi.setTmpPosition(progress);
						mHandler.post(mUpdateResults);
					}
				}

				@Override
				public void onStartTrackingTouch(SeekBar seekBar) {}
			});

			mPrevBtn.setOnClickListener(new OnClickListener () {
				public void onClick(View v)
				{
					mCon.playbackPrevious();
					updateInfo();
				}
			});

			mNextBtn.setOnClickListener(new OnClickListener () {
				public void onClick(View v)
				{
					mCon.playbackNext();
					try {
						// Give the server time to process
						Thread.currentThread().sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					updateInfo();
				}
			});

			mPlayBtn.setOnClickListener(new OnClickListener () {
				public void onClick(View v) {
					try {
						mCon.playbackPause();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					updateInfo();
				}
			});


		}

		this.updateInfo();
	}

	final private int MENU_BROWSE = 1;
	final private int MENU_PLAYLIST = 2;
	final private int MENU_UPDATE = 3;

	public boolean onCreateOptionsMenu(Menu menu)
	{
		menu.add(0, MENU_BROWSE, 0, "Browse files");
		menu.add(0, MENU_PLAYLIST, 0, "Playlist");
		menu.add(0, MENU_UPDATE, 0, "Update");
		return true;
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		switch (item.getItemId()) {
		case MENU_BROWSE:
			Log.w("----------------------", "browse");
			intent = new Intent(this, Browser.class);
			startActivity(intent);
			return true;
		case MENU_PLAYLIST:
			Log.w("----------------------", "playlist");
			intent = new Intent(this, Playlist.class);
			startActivity(intent);
			return true;
		case MENU_UPDATE:
			updateInfo();
			Log.w("----------------------", "update");
			return true;
		}
		return false;
	}

	private void updateInfo()
	{
		try {
			JSONObject obj = this.mCon.getInfo();

			this.mScreenUi.setTitle(obj.getString("TITLE"));
			String stat = "invalid status";
			switch(obj.getInt("STATUS"))
			{	
			case 0:
				stat = "playing"; this.scheduleStart(); break;
			case 1:
				stat = "paused"; this.scheduleStop(); break;
			case 2:
				stat = "stopped"; this.scheduleStop(); break;
			}
			this.mScreenUi.setStringStatus(stat);
			this.mScreenUi.setIntStatus(obj.getInt("STATUS"));
			this.mScreenUi.setArtist(obj.getString("ARTIST"));
			this.mScreenUi.setAlbum(obj.getString("ALBUM"));
			this.mScreenUi.setLength(obj.getInt("LENGTH"));
			this.mScreenUi.setPosition(obj.getInt("POSITION"));
			this.mScreenUi.setTmpPosition(obj.getInt("POSITION"));
			this.mScreenUi.setVolume(obj.getInt("VOLUME"));
			this.mScreenUi.setTmpVolume(obj.getInt("VOLUME"));
			
			Log.w("-------------", this.mScreenUi.getTitle());
			this.mHandler.post(this.mUpdateResults);
		}
		catch (NotPlayingException e)
		{
			this.mScreenUi.setStringStatus("stopped");
			this.mScreenUi.setIntStatus(2);
			this.mScreenUi.setTitle("Not playing");
			this.mScreenUi.setArtist("");
			this.mScreenUi.setAlbum("");
			this.mScreenUi.setLength(0);
			this.mScreenUi.setPosition(0);
			this.mScreenUi.setTmpPosition(0);

			this.mHandler.post(this.mUpdateResults);
			this.scheduleStop();
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void updateResultsInUi()
	{
		mVolume.setText(new Integer(this.mScreenUi.getTmpVolume()).toString());		
		mVolumeBar.setSecondaryProgress(this.mScreenUi.getVolume());
		mVolumeBar.setProgress(this.mScreenUi.getTmpVolume());
		mTime.setText(this.mScreenUi.getTime());
		mTimeBar.setMax(this.mScreenUi.getLength());
		mTimeBar.setSecondaryProgress(this.mScreenUi.getPosition());
		mTimeBar.setProgress(this.mScreenUi.getTmpPosition());

		mTitle.setText(this.mScreenUi.getTitle());
		//mStatus.setText(this.mScreenUi.getStringStatus()+" ");
		mArtist.setText(this.mScreenUi.getArtist());
		mAlbum.setText(this.mScreenUi.getAlbum());
		mTotaltime.setText(this.mScreenUi.getTotaltime());
		if(this.mScreenUi.getIntStatus() == 0)
			mPlayBtn.setImageResource(android.R.drawable.ic_media_pause);
		else
			mPlayBtn.setImageResource(android.R.drawable.ic_media_play);
	}

	private void updateSeekbar()
	{
		mTime.setText(this.mScreenUi.getTime());
		mTimeBar.setMax(this.mScreenUi.getLength());
		mTimeBar.setSecondaryProgress(this.mScreenUi.getPosition());
		mTimeBar.setProgress(this.mScreenUi.getTmpPosition());
	}

	class UpdateProgressBar extends TimerTask {
		public void run()
		{	
			// Get position and length of track 
			int pos = mScreenUi.getPosition();
			int len = mScreenUi.getLength();

			if(len <= pos)
			{
				// Retrieve new information from server about 1 second after runout
				if(len+1000 < pos)
					updateInfo();
				else
				{
					mScreenUi.setPosition(pos+1000);
					mScreenUi.setTmpPosition(pos+1000);
				}
			}
			// Move progressBar 1 second
			else
			{
				pos = pos+1000;
				mScreenUi.setPosition(pos);
				mScreenUi.setTmpPosition(pos);
				mHandler.post(mUpdateSeekbar);
			}
		}
	}

	// Start progressBar updater
	private void scheduleStart()
	{
		if(this.mTimer == null)
		{
			this.mTimer = new Timer();
			this.mTimer.schedule(new UpdateProgressBar(), 0, 1000);
		}
	}

	// Stop progressBar updater
	private void scheduleStop()
	{
		if(this.mTimer != null)
		{
			this.mTimer.cancel();
			this.mTimer = null;
		}
	}

	public void onResume() {
		Log.w("RESUME", "Now resuming");
		super.onResume();
		updateInfo();
		mHandler.post(mUpdateResults);
	}

	public void onRestart() {
		Log.w("RESTART", "Now restarting");
		super.onRestart();
		updateInfo();
		mHandler.post(mUpdateResults);
	}

	public void onPause() {
		super.onPause();
		Log.w("PAUSE", "Now pausing Infoscreen");
		this.scheduleStop();
	}

	public void onStop() {
		super.onStop();
		Log.w("STOP", "Now stopping Infoscreen");
		this.scheduleStop();
	}
}